package com.tianhua.javs.core.engine.pipeline;

import com.tianhua.javs.client.bean.*;
import com.tianhua.javs.client.enums.SegmentSceneEnum;
import com.tianhua.javs.client.func.IScriptFunc;
import com.tianhua.javs.core.constant.TagConstants;
import com.tianhua.javs.core.engine.PipelineTranslator;
import com.tianhua.javs.core.engine.handler.*;
import com.tianhua.javs.core.parse.JavsContentParseService;
import com.tianhua.javs.core.parse.SegmentSpreadParseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;


/**
 * Description:javs 赋值语句处理
 * date: 2022/2/11
 *
 * @author shenshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
@Component(value = "assignPipelineTranslator")
@Slf4j
public class AssignPipelineTranslator implements PipelineTranslator {
    @Resource(name = "assignFunc")
    private IScriptFunc assignFunc;

    @Autowired
    private BOHandler boHandler;

    @Autowired
    private DOHandler doHandler;

    @Autowired
    private DTOHandler dtoHandler;

    @Autowired
    private MethodHandler methodHandler;

    @Autowired
    private BasicParamHandler basicParamHandler;

    @Autowired
    private ConstructHandler constructHandler;

    @Autowired
    private SegmentSpreadParseService segmentSpreadParseService;

    @Autowired
    private JavsContentParseService javsContentParseService;

    @Override
    public String translateKeyWard(JavsTranslateContextBean translateContextBean, String javsShell, String keyWard) {
        TranslateResultBean translateResultBean;
        int index = keyWard.indexOf("(");
        if(index < 0){
            //不存在函数引用赋值
            //1.普通局部变量声明
            //2.对象之间的属性赋值
            translateResultBean = basicParamHandler.handleTranslate(javsShell, keyWard, translateContextBean, SegmentSceneEnum.LOCAL_PARAM_REFER);
            if(translateResultBean.isMatch()){
                return translateResultBean.getSegment();
            }
        }

        //构造函数引用
        translateResultBean = constructHandler.handleTranslate(javsShell, keyWard, translateContextBean, SegmentSceneEnum.CONSTRUCT_REFER);
        if(translateResultBean.isMatch()){
            return translateResultBean.getSegment();
        }

        //其他函数引用函数引用
        //1.静态方法
        //2.对象方法
        //3.链式引用调用方法
        if(keyWard.contains(".") && keyWard.endsWith(TagConstants.BRACKET_RIGHT)){
            //静态方法调用
            if(javsContentParseService.checkStaticMethodRefer(keyWard)){
                translateResultBean = methodHandler.handleTranslate(javsShell, keyWard, translateContextBean, SegmentSceneEnum.STATIC_METHOD);
                if(translateResultBean.isMatch()){
                    return translateResultBean.getSegment();
                }
            }
            String [] referArr = keyWard.split("\\.");
            String varCode = referArr[0];

            //不存在链式调用
            if(referArr.length == 2){
                translateResultBean = methodHandler.handleTranslate(javsShell, keyWard, translateContextBean, SegmentSceneEnum.OBJECT_METHOD);
                if(translateResultBean.isMatch()){
                    return translateResultBean.getSegment();
                }

                if(varCode.toLowerCase().endsWith("bo")){
                    translateResultBean = boHandler.handleTranslate(javsShell, keyWard, translateContextBean, SegmentSceneEnum.MODEL_ASSIGN);
                    if(translateResultBean.isMatch()){
                        return translateResultBean.getSegment();
                    }
                }

                if(varCode.toLowerCase().endsWith("do")){
                    translateResultBean = doHandler.handleTranslate(javsShell,keyWard,translateContextBean, SegmentSceneEnum.MODEL_ASSIGN);
                    if(translateResultBean.isMatch()){
                        return translateResultBean.getSegment();
                    }
                }

                if(varCode.toLowerCase().endsWith("dto")){
                    translateResultBean = dtoHandler.handleTranslate(javsShell, keyWard, translateContextBean, SegmentSceneEnum.MODEL_ASSIGN);
                    if(translateResultBean.isMatch()){
                        return translateResultBean.getSegment();
                    }
                }

            }

            else if(referArr.length == 3){
                if(referArr[0].toLowerCase().endsWith("do")){
                    translateResultBean = doHandler.handleTranslate(javsShell,keyWard,translateContextBean, SegmentSceneEnum.MODEL_BEAN_ASSIGN);
                    if(translateResultBean.isMatch()){
                        return translateResultBean.getSegment();
                    }
                }

                if(referArr[0].toLowerCase().endsWith("bo")){
                    translateResultBean = boHandler.handleTranslate(javsShell, keyWard, translateContextBean, SegmentSceneEnum.MODEL_BEAN_ASSIGN);
                    if(translateResultBean.isMatch()){
                        return translateResultBean.getSegment();
                    }
                }

                if(referArr[0].toLowerCase().endsWith("dto")){
                    translateResultBean = dtoHandler.handleTranslate(javsShell, keyWard, translateContextBean, SegmentSceneEnum.MODEL_BEAN_ASSIGN);
                    if(translateResultBean.isMatch()){
                        return translateResultBean.getSegment();
                    }
                }
            }
        }

        TranslateResultBean assignResultBean = assignFunc.translate(keyWard,translateContextBean.getCurrentScriptMethodBean().getScriptVarMap());

        if(assignResultBean == null){
            log.warn("assign not match, keyward = {}",keyWard);
            return keyWard;
        }

        ScriptVarMappingBean scriptVarMappingBean = assignResultBean.getMatchSegmentBean().getScriptVarMappingBean();
        if(scriptVarMappingBean != null){
            String varName = javsShell.split(TagConstants.EQ)[0].trim();
            scriptVarMappingBean.setJavsVarCode(varName);
            scriptVarMappingBean.setJavaCode(varName);
            translateContextBean.getCurrentScriptMethodBean().addRunTimeVar(scriptVarMappingBean);
        }

        //这里代表整个赋值语句处理完成，支持 基本类型的变量声明 复合对象的变量声明
        return segmentSpreadParseService.getBlankPrefix(javsShell) + translateResultBean.getSegmentClass() + " " + javsShell.replace(keyWard,translateResultBean.getSegment()).trim() + ";";
    }
}
